#include "Acceptor.h"
#include"Logger.h"

#include<sys/types.h>
#include<sys/socket.h>
#include<errno.h>
#include<unistd.h>

static int createNonblocking()
{
    int sockfd = ::socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_TCP);
    if(sockfd<0)
    {
        LOG_FATAL("%s:%s:%d listen sockfd create err:%d \n", __FILE__,__FUNCTION__, __LINE__,errno);
    }
    return sockfd;
}

Acceptor::Acceptor(EventLoop *loop, const InetAddress &listenAddr, bool reuseport)
    : loop_(loop)
    , acceptSocket_(createNonblocking()) //socket
    , acceptChannel_(loop, acceptSocket_.fd())
    , listenning_(false)
{
    acceptSocket_.setReuseAddr(true);
    acceptSocket_.setReusePort(true);
    acceptSocket_.bindAddress(listenAddr); //bind

    //注册读事件回调，有新连接就调用此回调
    acceptChannel_.setReadCallback(std::bind(&Acceptor::handleRead, this));

}
Acceptor::~Acceptor()
{
    acceptChannel_.disableALL();
    acceptChannel_.remove();
}




void Acceptor::listen()
{
    listenning_ = true;
    acceptSocket_.listen();
    acceptChannel_.enableReading();
}

//listenfd有事件发生，新用户连接
void Acceptor::handleRead()
{
    InetAddress peerAddr;
    int connfd = acceptSocket_.accept(&peerAddr);
    if(connfd >= 0)
    {
        if(newConnectionCallback_)
        {
            newConnectionCallback_(connfd, peerAddr);
        }
        else{
            ::close(connfd);
        }
    }
    else
    {
        LOG_ERROR("%s:%s:%d  accept err:%d \n", __FILE__,__FUNCTION__, __LINE__,errno);
        if(errno == EMFILE)
        {
            LOG_ERROR("%s:%s:%d  sockfd reached limite err:%d \n", __FILE__,__FUNCTION__, __LINE__,errno);
        }
    }
}